import pymysql
from pymysql import OperationalError,ProgrammingError,InternalError
import traceback,re
'''为了解决 一个表中 多个键的唯一性
需要使用 unique（）方法来设置多个键的唯一
注意 使用 unique（）方法设置的key 不是该表的主键
MySQL 中没有多个主键，只有主键、外键、组合键、索引
不能同时存在多个独立的 PRIMARY KEY，但是 可以有多个 unique
使用unique（）语句来确保指定key的唯一性，同时也保证了 主键的唯一性
'''
config = {
    'host': '127.0.0.1',
    'port': 3306,
    'user': 'root',
    'passwd': '123456',
    'db': 'py01db',
    'charset': 'utf8'
}


def connect_db():
    try:
        connect = pymysql.connect(**config)
        return connect
    except OperationalError as e:
        # OperationalError 用于捕捉PyMySQL的错误机制，目的是不会出现异常
        print(e)


def query_insert_one(table_name, data):
    insert_data = [
        ('u_uid', '12345678903'),
        ('u_name', 'Tony 托尼')
        ('u_age',40)
    ]
    head = []
    values = []
    temps = []
    for item in insert_data:
        head.append(item[0])
        values.append(item[1])
        temps.append('%s')
        # if type(item[1]) == type(1):
        #     temps.append('%d')
        # else:
        #     temps.append('%s')
    '''将 List 转换成 tuple 元组数据集合'''
    head = tuple(head)
    values = tuple(values)
    temps = tuple(temps)
    '''拼接 数据库执行语句 字符串'''
    base_url = "insert into"
    base_url += table_name + str(head) +'values'+str(temps)
    '''利用正则 去掉  ' 单引号'''
    base_url = re.sub(r'\'','',base_url)
    connect = connect_db()
    if connect:
        cursor = connect.cursor(cursor=pymysql.cursors.DictCursor)
        try:
            '''使用 execute() 方法执行SQL语句 防注入'''
            cursor.execute(base_url,values)
            '''提交修改数据 并保存'''
            connect.commit()
        except:
            traceback.print_exc()
            connect.rollback()
        finally:
            cursor.close()
            connect.close()



    # base_url = "insert into"
    # base_url += table_name + '('
    # for item in insert_data:
    #     base_url += item[0] + ','
    #     temp_string += '%s,'
    #
    #
    # print(temp_string)
    #     base_url = base_url[:-1] + ') values('
    # print(base_url)


    # connect = connect_db()
    # if connect:
    #     cursor = connect.cursor(cursor=pymysql.cursors.DictCursor)
    #     try:
    #         cursor.execute(base_url,values)
    #         connect.commit()
    #     except:
    #         traceback.print_exc()
    #         connect.rollback()
    #     finally:
    #         cursor.close()
    #         connect.close()


def query_find_all(table_name):
    if table_name is None:
        return '****************'
    # 使用正则 过滤 非法字符


    sql_string = "select * from " + table_name
    connect = connect_db()
    if connect:
        cursor = connect.cursor(cursor=pymysql.cursors.DictCursor)
        try:
            cursor.execute(sql_string)
            return cursor.fetchall()
        except ProgrammingError as e:
            print(e)
            # traceback.print_exc()
            connect.rollback()
        finally:
            cursor.close()
            connect.close()
    else:
        return None
#
# def query_search_rows(table_name,condition):
#     # 对table_name 进行 正则
#     sql_string = "select u_uid,u_name from stu where u_uid='%s' and u_name='%s'" % ("'or 1=1 --",'Pony pass')
#     '''
#     SQL 注入是比较常见的网络攻击方式之一，它不是利用操作系统的Bug来实现攻击的
#     而是通过对程序员在编程时的疏忽，通过SQL语句，实现无账号登录，甚至是修改数据库
#     注入总体思路：
#     1.寻找到SQL注入的位置
#     2.判断服务类型和后台数据类型
#     3.针对不同的服务器和数据库进行SQL注入攻击
#
#
#     SQL注入攻击的方式1：
#     方式1：
#     通过字符串拼接查询，造成注入
#     #u_uid=''or 1=1 --' and u_name='Pony pass'
#     相当于 u_uid=''或者'1=1' 那么这个条件就一定成立
#     -- 表示注释 它将后面的语句进行注释 不起作用 ，这样语句就能永远正常执行
#     '''
#     # select u_uid,u_name from stu where u_uid=''or 1=1 --' and u_name='Pony pass'
#     print(sql_string)
#     '''解决方式：参数化语句'''
#     # sql_string = "select u_uid,u_name from stu where u_uid='%s' and u_name='%s'" ,("'or 1=1 --", 'Pony pass')
#     connect_db().cursor().execute("select u_uid,u_name from stu where u_uid='%s' and u_name='%s'",("'or 1=1 --", 'Pony pass'))






def main():
    # rows = query_find_all('stu')
    # if rows:
    #     print(rows)
    query_insert_one('stu','')

# if __name__ == '__main__':
main()




